#include "APP_Message.h"



//字节数组 转 message结构体
Message* APP_Bytes_To_Message(char* bytes)
{
    //定义一个消息结构体 并分配空间
    Message* msg = (Message*) malloc(sizeof(Message));
    if(msg == NULL)
    {
        perror("消息结构体分配空间失败 ");
        return NULL;
    }
    //对消息结构体 进行赋值
    
    msg->conn_type = bytes[0];
    msg->id_len = bytes[1];
    msg->msg_len = bytes[2];
    //为消息数据指针 指向的空间分配内存
    msg->payload = (char*) malloc(sizeof(char) * (msg->id_len + msg->msg_len + 1));
    memcpy(msg->payload,(bytes + 3),msg->msg_len + msg->id_len);
    return msg;
}

//message结构体 转 字节数组
char* APP_Message_To_Bytes(Message* msg,int * bytes_len)
{
    *bytes_len = 3 + msg->id_len + msg->msg_len;
    //定义字节数组 并分配空间 
    char* bytes = malloc(sizeof(char) * (*bytes_len + 1));
    if(bytes == NULL)
    {
        perror("字节数组分配空间失败 ");
        return NULL;
    }
    bytes[0] = msg->conn_type;
    bytes[1] = msg->id_len;
    bytes[2] = msg->msg_len;
    memcpy((bytes + 3),msg->payload,(msg->id_len + msg->msg_len));
    bytes[*bytes_len] = '\0';
    return bytes;
}

//json字符串 转 message结构体
Message* APP_Json_To_Message(char* json_str)
{
    //定义消息结构体 并分配空间
    Message* Msg = (Message*) malloc(sizeof(Message));
    if(Msg == NULL)
    {
        perror("消息结构体分配空间失败 ");
        return NULL;
    }
    
    //解析字符串json对象
    cJSON* json = cJSON_Parse(json_str);
    if(json == NULL)
    {
        log_info("cJSON_Parse函数解析json字符串失败");
        perror("解析字符串json对象创建失败 ");
        return NULL;
    }
    cJSON* Conn_type = cJSON_GetObjectItemCaseSensitive(json,"conn_type");
    cJSON* id = cJSON_GetObjectItemCaseSensitive(json,"id");
    cJSON* msg = cJSON_GetObjectItemCaseSensitive(json,"msg");

    //为消息结构体赋值
    Msg->conn_type = Conn_type->valueint;

    // 定义id字符数组 并分配空间
    Msg->id_len = strlen(id->valuestring) / 2;
    char* id_str = (char*)malloc(sizeof(char) * (Msg->id_len + 1));
    if(id_str == NULL)
    {
        perror("id数组空间分配失败 ");
        return NULL;
    }
    int ret = APP_COM_HexStr_To_Bytes(id->valuestring,id_str,Msg->id_len * 2);
    if(ret != 0)
    {
        perror("转化成id_str异常 ");
        return NULL;
    }
    
    // 定义消息字符数组 并分配空间
    Msg->msg_len = strlen(msg->valuestring) / 2;
    char* msg_str = (char*)malloc(sizeof(char) * (Msg->msg_len + 1));
    if(msg_str == NULL)
    {
        perror("消息数据数组空间分配失败 ");
        return NULL;
    }
    ret = APP_COM_HexStr_To_Bytes(msg->valuestring,msg_str,Msg->msg_len * 2);
    if(ret != 0)
    {
        perror("转化成msg_str异常 ");
        return NULL;
    }

    //为消息结构体消息数据数组 分配空间并 赋值
    Msg->payload = (char*)malloc(sizeof(char) * (Msg->id_len + Msg->msg_len + 1));
    memcpy(Msg->payload,id_str,Msg->id_len);
    memcpy(Msg->payload + Msg->id_len,msg_str,Msg->msg_len);

    //释放id_str和msg_str资源
    free(id_str);
    free(msg_str);
    //释放字符串解析json对象
    cJSON_Delete(json);

    return Msg;
}

//message结构体 转 json字符串
char* APP_Message_To_Json(Message* msg)
{
    //创建 json对象
    cJSON* json = cJSON_CreateObject();
    if(json == NULL)
    {
        perror("字符串json对象创建失败 ");
        return NULL;
    }

    //向json对象添加键值
    cJSON_AddNumberToObject(json,"conn_type",msg->conn_type);

    //定义 id十六进制字符数组 并分配空间
    char* id_hexstr = (char*)malloc(sizeof(char) * (msg->id_len * 2 + 1));
    int ret = APP_COM_Bytes_To_HexStr(id_hexstr,msg->payload,msg->id_len);
    if(ret != 0)
    {
        perror("转化成id_hexstr异常 ");
        return NULL;
    }

    //定义 消息数据十六进制字符数组 并分配空间
    char* msg_hexstr = (char*)malloc(sizeof(char) * (msg->msg_len * 2 + 1));
    ret = APP_COM_Bytes_To_HexStr(msg_hexstr,(char*)(msg->payload + msg->id_len),msg->msg_len);
    if(ret != 0)
    {
        perror("转化成msg_hexstr异常 ");
        return NULL;
    }
    cJSON_AddStringToObject(json,"id",id_hexstr);
    cJSON_AddStringToObject(json,"msg",msg_hexstr);

    //将json对象内容转化为 字符串
    char* json_str = cJSON_PrintUnformatted(json);
    if(json_str == NULL)
    {
        perror("json对象转字符串失败 ");
        return NULL;
    }
    //释放 id_hexstr 和 msg_hexstr资源
    free(id_hexstr);
    free(msg_hexstr);
    //释放json对象
    cJSON_Delete(json);
    
    return json_str;
}
